package com.authine.cloudpivot.web.api.secondopen.controller;

import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.enums.ProcessType;
import com.authine.cloudpivot.web.api.secondopen.domain.AjaxResult;
import com.authine.cloudpivot.web.api.secondopen.domain.BudgetLog;
import com.authine.cloudpivot.web.api.secondopen.domain.Monthlybudgetadjustrecord;
import com.authine.cloudpivot.web.api.secondopen.domain.Qnyssq;
import com.authine.cloudpivot.web.api.secondopen.service.BudgetMaintainService;
import com.authine.cloudpivot.web.api.utils.DateUtil;
import com.authine.cloudpivot.web.api.utils.StringUtils;
import io.jsonwebtoken.lang.Collections;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 预算维护控制器
 *
 */
@Api(value = "二开接口", tags = "预算维护控制器")
@RestController
@RequestMapping("/api/budgetMaintain")
public class BudgetMaintainController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(BudgetMaintainController.class);

    @Autowired
    private BudgetMaintainService budgetMaintainService;

    /**
     * 全年预算申请保存验证，验证额度是否申请
     *
     */
    @PostMapping("/checkSaveAnnualBudget")
    public AjaxResult checkSaveAnnualBudget(@RequestBody Qnyssq qnyssq){
        log.info("---------------方法：checkSaveAnnualBudget参数："+ JSON.toJSONString(qnyssq));
        if(qnyssq==null || StringUtils.isBlank(qnyssq.getNf()) || StringUtils.isBlank(qnyssq.getOneaccountcode()) || StringUtils.isBlank(qnyssq.getTwoaccountcode()) || StringUtils.isBlank(qnyssq.getYscbzx())){
//            log.info("---------------方法：checkSaveAnnualBudget参数：年份："+qnyssq.getNf()+"，总账户编码："+qnyssq.getOneaccountcode()+",分帐户编码："+qnyssq.getTwoaccountcode()+"，成本中心："+qnyssq.getYscbzx());
            return AjaxResult.error(300,"参数有误，不能存在为空的参数");
        }
        List<Qnyssq> qnyssqs=budgetMaintainService.checkAnnualBudget(qnyssq);
        log.info("---------------返回信息："+ JSON.toJSONString(qnyssqs));
        if(!Collections.isEmpty(qnyssqs)){
            return AjaxResult.error(300,"已存在该年度，该总账户编码，分帐户编码，成本中心的年度预算申请数据！");
        }
        return AjaxResult.success(qnyssqs);
    }



    /**
     * 根据年份，总账户编码，分帐户编码，成本中心查询预算额度信息
     *
     */
    @PostMapping("/getBudgetQuotaByParam")
    public AjaxResult getBudgetQuotaByParam(@RequestBody Monthlybudgetadjustrecord monthlybudgetadjustrecord){
        log.info("---------------方法：getBudgetQuotaByParam："+ JSON.toJSONString(monthlybudgetadjustrecord));
        if(monthlybudgetadjustrecord==null || StringUtils.isBlank(monthlybudgetadjustrecord.getYear()) || StringUtils.isBlank(monthlybudgetadjustrecord.getOneSubject()) || StringUtils.isBlank(monthlybudgetadjustrecord.getTwoSubject()) || StringUtils.isBlank(monthlybudgetadjustrecord.getCostCenter())){
//            log.info("---------------方法：getBudgetQuotaByParam参数：年份："+qnyssq.getNf()+"，总账户编码："+qnyssq.getOneaccountcode()+",分帐户编码："+qnyssq.getTwoaccountcode()+"，成本中心："+qnyssq.getYscbzx());
            return AjaxResult.error(300,"验证失败，参数有误，不能存在为空的参数");
        }
        List<Monthlybudgetadjustrecord> monthlybudgetadjustrecords=budgetMaintainService.getBudgetQuota(monthlybudgetadjustrecord);
        log.info("---------------返回信息："+ JSON.toJSONString(monthlybudgetadjustrecords));
        return AjaxResult.success(monthlybudgetadjustrecords);
    }



    /**
     * 根据年份，月份，总账户编码，分帐户编码，成本中心查询预算额度信息(用于报销判断)
     *
     */
    @PostMapping("/getBudgetQuotaByParams")
    public AjaxResult getBudgetQuotaByParams(@RequestBody List<Monthlybudgetadjustrecord> monthlybudgetadjustrecords){
        log.info("---------------方法：getBudgetQuotaByParams："+ JSON.toJSONString(monthlybudgetadjustrecords));
        if(monthlybudgetadjustrecords==null || Collections.isEmpty(monthlybudgetadjustrecords)){
            return AjaxResult.error(300,"验证失败，参数有误，不能存在为空的参数");
        }
        for (Monthlybudgetadjustrecord monthlybudgetadjustrecord : monthlybudgetadjustrecords) {
            if(StringUtils.isBlank(monthlybudgetadjustrecord.getOneSubject()) || StringUtils.isBlank(monthlybudgetadjustrecord.getTwoSubject()) || StringUtils.isBlank(monthlybudgetadjustrecord.getCostCenter())){
//            log.info("---------------方法：getBudgetQuotaByParam参数：年份："+qnyssq.getNf()+"，总账户编码："+qnyssq.getOneaccountcode()+",分帐户编码："+qnyssq.getTwoaccountcode()+"，成本中心："+qnyssq.getYscbzx());
                return AjaxResult.error(300,"验证失败，科目信息数据不全");
            }
            int year=DateUtil.getCurrentYear();
            int month=DateUtil.getCurrentMonth();
            monthlybudgetadjustrecord.setYear(String.valueOf(year));
            monthlybudgetadjustrecord.setMonth(String.valueOf(month));
            List<Monthlybudgetadjustrecord> monthlybudgets=budgetMaintainService.getBudgetQuota(monthlybudgetadjustrecord);
            if(Collections.isEmpty(monthlybudgets)){
                return AjaxResult.error(300,"验证失败，不存在一级科目为"+monthlybudgetadjustrecord.getOneSubjectName()+",二级科目为"+monthlybudgetadjustrecord.getTwoSubjectName()+"的预算额度数据");
            }
            //如果报销额度大于剩余额度，则不让提交
            if(monthlybudgetadjustrecord.getAvailableQuota().compareTo(monthlybudgets.get(0).getAvailableQuota())==1){
                return AjaxResult.error(300,"验证失败，一级科目为"+monthlybudgetadjustrecord.getOneSubjectName()+",二级科目为"+monthlybudgetadjustrecord.getTwoSubjectName()+"的预算额度不足");
            }
        }
        return AjaxResult.success("验证通过");
    }


    /**
     * 只有科目字段为是费控，才根据年份，总账户编码，分帐户编码，成本中心查询预算额度信息，（用于调整开窗反显和报销提交判断是否扣减）
     *
     */
    @PostMapping("/verificationBudgetQuota")
    public AjaxResult verificationBudgetQuota(@RequestBody List<Monthlybudgetadjustrecord> monthlybudgetadjustrecord){
        log.info("---------------方法：getBudgetQuotaByParam："+ JSON.toJSONString(monthlybudgetadjustrecord));
        if(Collections.isEmpty(monthlybudgetadjustrecord)){
            return AjaxResult.error(300,"提交失败，请选择科目信息！");
        }else{
            for (Monthlybudgetadjustrecord monthlybuds : monthlybudgetadjustrecord) {
//                if(StringUtils.isBlank(monthlybuds.getYear())){
//                    monthlybuds.setYear(String.valueOf(DateUtil.getCurrentYear()));
//                }
                monthlybuds.setYear(String.valueOf(DateUtil.getCurrentYear()));
                if(monthlybuds==null || StringUtils.isBlank(monthlybuds.getOneSubject()) || StringUtils.isBlank(monthlybuds.getTwoSubject()) || StringUtils.isBlank(monthlybuds.getCostCenter())){
//            log.info("---------------方法：getBudgetQuotaByParam参数：年份："+qnyssq.getNf()+"，总账户编码："+qnyssq.getOneaccountcode()+",分帐户编码："+qnyssq.getTwoaccountcode()+"，成本中心："+qnyssq.getYscbzx());
                    return AjaxResult.error(300,"提交失败，数据有误，一级科目，二级科目，成本中心不能为空");
                }
                List<Monthlybudgetadjustrecord> monthlybudgetadjustrecords=budgetMaintainService.getBudgetQuota(monthlybuds);
                if(Collections.isEmpty(monthlybudgetadjustrecords)){
                    return AjaxResult.error(300,"提交失败，不存在一级科目为"+monthlybuds.getOneSubject()+",二级科目为"+monthlybuds.getTwoSubject()+"，成本中心为"+monthlybuds.getCostCenter()+"该年度预算的数据");
                }
            }
        }
        return AjaxResult.success("验证成功");
    }


    /**
     * 月度预算追加和月度预算减少 追加和减少额度
     *
     * @param objId
     * @return
     */
    @RequestMapping(value="/budgetAmendmentZjia",method = {RequestMethod.POST ,RequestMethod.GET })
    @ApiOperation(value = "月度预算追加和月度预算减少流程追加和减少额度", notes = "月度预算追加和月度预算减少流程追加和减少额度")
    @ApiImplicitParams({
    @ApiImplicitParam(name = "objId", value = "业务对象id", dataType = "String", paramType = "query")
    })
    public void budgetAmendmentZjia(String objId,String processCode,String identtify) {
        log.info("获取参数:objId={},processCode={},identtify={}", objId,processCode,identtify);
        if (StringUtils.isBlank(objId) || StringUtils.isBlank(processCode) || StringUtils.isBlank(identtify)) {
            log.info("参数不完整，直接结束");
            return;
        }
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(processCode, objId);
        if (bizObject == null) {
            log.info("业务对象不存在");
            return;
        }
        String wId = bizObject.getWorkflowInstanceId();
        log.info("TargetOwner:wId={}", wId);
        WorkflowInstanceModel wiModel = super.getWorkflowInstanceFacade().getWorkflowInstance(wId);
        if (wiModel == null) {
            log.info("业务流程对象不存在");
        }

        String cbzx = (String) bizObject.get("cbzx");
        String oneSubjectCode = (String) bizObject.get("oneSubjectCode");
        String twoSubjectCode = (String) bizObject.get("twoSubjectCode");
        String year=String.valueOf(DateUtil.getCurrentYear());
        Monthlybudgetadjustrecord monthlybudgetadjustrecord=new Monthlybudgetadjustrecord();
        monthlybudgetadjustrecord.setYear(year);
        monthlybudgetadjustrecord.setOneSubject(oneSubjectCode);
        monthlybudgetadjustrecord.setTwoSubject(twoSubjectCode);
        monthlybudgetadjustrecord.setCostCenter(cbzx);

        List<Map<String, Object>> ydzjSheetList=new ArrayList<>();
        if("ydyszjlc".equals(processCode)){
            //如果是预算增加流程，拿的就是预算增加子表
            ydzjSheetList = (List<Map<String, Object>>) bizObject.get("ydzjSheet");
        }else if("ysjslc".equals(processCode)){
            //如果是预算减少流程，拿的就是预算减少子表
            ydzjSheetList = (List<Map<String, Object>>) bizObject.get("ydjsSheet");
        }
        if(!Collections.isEmpty(ydzjSheetList)){
            for (int i = 0; i < ydzjSheetList.size(); i++) {
                String yf = String.valueOf(ydzjSheetList.get(i).get("yf"));
                BigDecimal tzys = (BigDecimal) ydzjSheetList.get(i).get("tzys");
                monthlybudgetadjustrecord.setMonth(yf);
                if(tzys==null || tzys.compareTo(BigDecimal.ZERO)==0){
                    continue;
                }else{
                    monthlybudgetadjustrecord.setModifiedBy("admin");
                    monthlybudgetadjustrecord.setModifiedTime(new Date());
                    if("ydyszjlc".equals(processCode)){
                        monthlybudgetadjustrecord.setTzys(tzys);
                        //中间表额度追加
                        int a=budgetMaintainService.addBudgetAmendment(monthlybudgetadjustrecord);
                        if(a>0){
                            log.info("-----------更新月度预算追加数据成功--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                            BudgetLog budgetLog=new BudgetLog();
                            //插入日志信息
                            BeanUtils.copyProperties(monthlybudgetadjustrecord,budgetLog);
                            budgetLog.setIncreaseLimit(tzys);
                            budgetLog.setProcessId(objId);
                            //如果是预算增加流程，
                            budgetLog.setProcessType(ProcessType.YDYSZJ.getCode());
                            budgetMaintainService.addBudgetLog(budgetLog);
                        }else{
                            log.info("-----------更新月度预算追加数据失败--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                        }
                    }else if("ysjslc".equals(processCode)){
                        BigDecimal ys=tzys;
                        //如果是增加，对于追减额度正数来说，那么额度为负数
                        if("1".equals(identtify)){
                            ys=tzys.multiply(new BigDecimal(-1));
                        }
                        monthlybudgetadjustrecord.setTjys(ys);
                        //中间表额度计算
                        int a=budgetMaintainService.jsBudgetAmendment(monthlybudgetadjustrecord);
                        if(a>0){
                            log.info("-----------更新月度预算减少数据成功--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                            BudgetLog budgetLog=new BudgetLog();
                            //插入日志信息
                            BeanUtils.copyProperties(monthlybudgetadjustrecord,budgetLog);
                            if("2".equals(identtify)){
                                budgetLog.setReductionLimit(tzys);
                            }else{
                                budgetLog.setIncreaseLimit(tzys);
                            }
                            budgetLog.setProcessId(objId);
                            //如果是预算减少流程，
                            budgetLog.setProcessType(ProcessType.YDYSJS.getCode());

                            budgetMaintainService.addBudgetLog(budgetLog);
                        }else{
                            log.info("-----------更新月度预算减少数据失败--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                        }
                    }

                }
            }
        }else{
            log.info("预算子表数据为空，无法扣减预算");
        }

    }


    /**
     * 月度预算调整额度，一开始扣除调减预算，结束调增预算，驳回到开始还原调减预算
     *
     * @param objId
     * @return
     */
    @RequestMapping(value="/adjustmentBudget",method = {RequestMethod.POST ,RequestMethod.GET })
    @ApiOperation(value = "月度预算调整额度", notes = "月度预算调整额度")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "objId", value = "业务对象id", dataType = "String", paramType = "query")
    })
    public void adjustmentBudget( String objId,String processCode,String identtify) {
        log.info("获取参数:objId={}", objId);
        if (StringUtils.isBlank(objId)) {
            log.info("参数不完整，直接结束");
            return;
        }
        //identtify=1 调增   identtify=2 调减     identtify=3  调减后驳回还原预算
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(processCode, objId);
        if (bizObject == null) {
            log.info("业务对象不存在");
            return;
        }
        String wId = bizObject.getWorkflowInstanceId();
        log.info("TargetOwner:wId={}", wId);
        WorkflowInstanceModel wiModel = super.getWorkflowInstanceFacade().getWorkflowInstance(wId);
        if (wiModel == null) {
            log.info("业务流程对象不存在");
        }
        //如果是流程结束调增
        String cbzx = (String) bizObject.get("cbzx");
        String oneSubjectCode = "";
        String twoSubjectCode = "";
        List<Map<String, Object>> ydzjSheetList=new ArrayList<>();
        //如果是开始调增预算
        if("1".equals(identtify)){
            oneSubjectCode = (String) bizObject.get("tzOneSubjectCode");
            twoSubjectCode = (String) bizObject.get("tzTwoSubjectCode");
            ydzjSheetList = (List<Map<String, Object>>) bizObject.get("ydysTzSheet");
        }else{
            //如果是流程结束调减
            oneSubjectCode = (String) bizObject.get("tjOneSubjectCode");
            twoSubjectCode = (String) bizObject.get("tjTwoSubjectCode");
            ydzjSheetList = (List<Map<String, Object>>) bizObject.get("ydysTjSheet");
        }

        String year=String.valueOf(DateUtil.getCurrentYear());
        Monthlybudgetadjustrecord monthlybudgetadjustrecord=new Monthlybudgetadjustrecord();
        monthlybudgetadjustrecord.setYear(year);
        monthlybudgetadjustrecord.setOneSubject(oneSubjectCode);
        monthlybudgetadjustrecord.setTwoSubject(twoSubjectCode);
        monthlybudgetadjustrecord.setCostCenter(cbzx);

        if(!Collections.isEmpty(ydzjSheetList)){
            for (int i = 0; i < ydzjSheetList.size(); i++) {
                String yf = String.valueOf(ydzjSheetList.get(i).get("yf"));
                monthlybudgetadjustrecord.setMonth(yf);
                monthlybudgetadjustrecord.setModifiedBy("admin");
                monthlybudgetadjustrecord.setModifiedTime(new Date());
                BigDecimal ys=null;
                //如果是结束调增预算
                if("1".equals(identtify)) {
                    ys = (BigDecimal) ydzjSheetList.get(i).get("tzys");
                    monthlybudgetadjustrecord.setIncreaseLimit(ys);
                    monthlybudgetadjustrecord.setReductionLimit(null);
                }else if("2".equals(identtify)){
                    //开始调减预算
                    ys = (BigDecimal) ydzjSheetList.get(i).get("tjys");
                    monthlybudgetadjustrecord.setReductionLimit(ys);
                    monthlybudgetadjustrecord.setIncreaseLimit(null);
                }else{
                    //驳回还原调减预算
                    ys = (BigDecimal) ydzjSheetList.get(i).get("tjys");
                    //驳回后将额度转成负数，进行冲抵
                    monthlybudgetadjustrecord.setReductionLimit(ys.multiply(new BigDecimal(-1)));
                    monthlybudgetadjustrecord.setIncreaseLimit(null);
                }
                if(ys==null || ys.compareTo(BigDecimal.ZERO)==0){
                    continue;
                }else{
                    //中间表额度调整
                    int a=budgetMaintainService.adjustmentBudgetData(monthlybudgetadjustrecord);
                    if(a>0){
                        log.info("-----------月度预算调整申请结束调用调增额度增加成功--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                        BudgetLog budgetLog=new BudgetLog();
                        //插入日志信息
                        BeanUtils.copyProperties(monthlybudgetadjustrecord,budgetLog);
                        budgetLog.setIncreaseLimit(ys);
                        if("1".equals(identtify) || "3".equals(identtify) ) {
                            //如果是调增或者驳回后还原额度，则算到日志增加额度中
                            budgetLog.setIncreaseLimit(ys);
                            budgetLog.setReductionLimit(new BigDecimal(0));
                        }else{
                            //如果是调减额度，则算到日志减少额度中
                            budgetLog.setReductionLimit(ys);
                            budgetLog.setIncreaseLimit(new BigDecimal(0));
                        }
                        budgetLog.setProcessId(objId);
                        //如果是预算增加流程，
                        budgetLog.setProcessType(ProcessType.YDYSTZ.getCode());
                        budgetMaintainService.addBudgetLog(budgetLog);
                    }else{
                        log.info("-----------月度预算调整申请结束调用调增额度增加失败--------{}", JSON.toJSONString(monthlybudgetadjustrecord));
                    }
                }

            }
        }else{
            log.info("月度预算调整申请调整额度数据为空");
        }

    }

}
